package  
{
	import org.flixel.*;
	
	/**
	 * ...
	 * @author Thomas Liu
	 */
	public class PlayState extends FlxState
	{
		[Embed (source = "../data/Background/Fence1.png")] private var fence1_img:Class;
		[Embed (source = "../data/Background/Fence2.png")] private var fence2_img:Class;
		[Embed (source = "../data/Background/Fence3.png")] private var fence3_img:Class;
		[Embed (source = "../data/Background/Fence4.png")] private var fence4_img:Class;
		[Embed (source = "../data/Background/FenceGrass.png")] private var grass_img:Class;
		[Embed (source = "../data/Background/Track.png")] private var track_img:Class;		
		[Embed (source = "../data/Background/Hills.png")] private var hill_img:Class;		
		[Embed (source = "../data/Background/Mountains.png")] private var mountain_img:Class;		
		[Embed (source = "../data/Background/Sky.png")] private var sky_img:Class;
		[Embed (source = "../data/Background/Foreground_LIGHT.png")] private var grass2_img:Class;
		[Embed (source = "../data/Background/Foreground_DARK.png")] private var grass3_img:Class;
		
		// Obstacles
		[Embed (source = "../data/Obstacles/Bench_FRONT.png")] private var bench_front_img:Class;
		[Embed (source = "../data/Obstacles/Bench_BACK.png")] private var bench_back_img:Class;
		[Embed (source = "../data/Obstacles/Collision/Bench_COL.png")] private var bench_col_img:Class;
		
		[Embed (source = "../data/Obstacles/Barrels_FRONT.png")] private var barrels_front_img:Class;
		[Embed (source = "../data/Obstacles/Barrels_BACK.png")] private var barrels_back_img:Class;
		[Embed (source = "../data/Obstacles/Collision/Barrels_COL.png")] private var barrels_col_img:Class;		
		
		
		private var fenceImages:Array = [fence1_img, fence2_img, fence3_img, fence4_img];		
		
		private var obstacleImages:Array = [
			[bench_front_img, bench_back_img, bench_col_img, 53],
			[barrels_front_img, barrels_back_img, barrels_col_img, 44],	
											];
		
		public var player1:Player;
		public var player2:Player;
		public var topCamera:FlxCamera;
		public var bottomCamera:FlxCamera;
		
		public var fences:FlxGroup = new FlxGroup();
		public var backGrasses:FlxGroup = new FlxGroup();
		public var tracks:FlxGroup = new FlxGroup();
		public var skies:FlxGroup = new FlxGroup();
		public var mountains:FlxGroup = new FlxGroup();
		public var hills:FlxGroup = new FlxGroup();
		public var foreGrasses1:FlxGroup = new FlxGroup();
		public var foreGrasses2:FlxGroup = new FlxGroup();
		public var obstaclesForeground:FlxGroup = new FlxGroup();
		public var obstaclesBackground:FlxGroup = new FlxGroup();
		public var obstacles:FlxGroup = new FlxGroup();	// These aren't drawn, just for updating reasons
		
		override public function create():void 
		{
			FlxG.bgColor = 0xFFFFFFFF;
			super.create();
			
			// Populate the background images
			
			// TODO: Make a RepeatingBackground class to abstract some of this logic
			
			for (var i:int = 0; i < FlxG.width + 64; i += 64)	// Fence images are 64 px wide
			{
				addRepeatingObj(fences,fenceImages[(int)(Math.random() * 4)], i, 26);
			}
			for (i = 0; i < FlxG.width + 256; i += 256)	// These images are all the full screen size
			{
				addRepeatingObj(backGrasses, grass_img, i, 0);
				addRepeatingObj(tracks, track_img, i, 0);
				addRepeatingObj(hills, hill_img, i, 0, 0.5);
				addRepeatingObj(skies, sky_img, i, 0, 0.1);
				addRepeatingObj(mountains, mountain_img, i, 0, 0.25);
				addRepeatingObj(foreGrasses1, grass2_img, i, 0, 2.0);
				addRepeatingObj(foreGrasses2, grass3_img, i, 0, 3.0);
				
			}			
			
			player1 = new Player(34, 39, 0, 1);
			player2 = new Player(40, 53, 1, 3);
			
			topCamera = new FlxCamera(0, 0, FlxG.width, FlxG.height / 2);
			bottomCamera = new FlxCamera(0, FlxG.height / 2 * 3, FlxG.width, FlxG.height / 2);
			FlxG.addCamera(topCamera);
			FlxG.addCamera(bottomCamera);
			
			add(skies);
			add(mountains);
			add(hills);
			add(tracks);
			add(fences);
			add(backGrasses);
			
			add(obstaclesBackground);
			
			add(player1);
			add(player2);
			
			add(obstaclesForeground);
			
			add(foreGrasses1);
			add(foreGrasses2);
			
			add(obstacles);
		}
		
		public function addObstacle(fg:Class, bg:Class, col:Class, y:int) : void
		{
			var o:Obstacle = (Obstacle)(obstacles.getFirstAvailable());
			if (!o)
			{
				o = new Obstacle();
				obstaclesForeground.add(o.foregroundSprite);
				obstaclesForeground.add(o.collisionSprite);
				obstaclesBackground.add(o.backgroundSprite);
				obstacles.add(o);
			}
			var rightEdge:int = Math.max(topCamera.scroll.x, bottomCamera.scroll.x) + FlxG.width;
			o.spawn(fg, bg, col, rightEdge, y);
		}
		
		// Standard recycling code
		public function addRepeatingObj(group:FlxGroup, image:Class, x:int, y:int, scrollFactor:Number = 1.0) : void
		{
			var s:FlxSprite = (FlxSprite)(group.getFirstAvailable());
			if (!s)
			{
				s = new FlxSprite(x, y);
				group.add(s);
			}
			s.exists = true;
			s.x = x;
			s.scrollFactor.x = scrollFactor;
			s.loadGraphic(image);
		}
		
		// Figure out if we need to make a new repeating obj (because the farthest right one is not covering the screen)
		public function updateRepeatingObj(group:FlxGroup, image:Class, y:int, scrollFactor:Number = 1.0) : void
		{
			var leftEdge:int = Math.min(topCamera.scroll.x, bottomCamera.scroll.x) * scrollFactor;
			var rightEdge:int = Math.max(topCamera.scroll.x, bottomCamera.scroll.x) * scrollFactor + FlxG.width;
			
			var rightObj:int = 0;
			
			for each (var s:FlxSprite in group.members)
			{
				if (s.x + s.width < leftEdge && s.alive)
				{
					// Destroy ones that have gone off the left of the screen
					s.kill();
				}
				else
				{
					// Keep track of the right-most edge
					rightObj = Math.max(s.x + s.width, rightObj);
				}
			}
			
			// If we don't have full screen coverage, make a new repeating object at the correct location
			if (rightObj < rightEdge)
			{
				addRepeatingObj(group, image, rightObj, y, scrollFactor);
			}
		}
		
		override public function update():void 
		{
			super.update();
			topCamera.scroll.x = Math.max(player1.x - 64, 0);
			bottomCamera.scroll.x = Math.max(player2.x - 64, 0);
			updateRepeatingObj(fences, fenceImages[(int)(Math.random() * 4)], 26);
			updateRepeatingObj(backGrasses, grass_img, 0);
			updateRepeatingObj(tracks, track_img, 0);
			updateRepeatingObj(skies, sky_img, 0, 0.1);
			updateRepeatingObj(hills, hill_img, 0, 0.5);
			updateRepeatingObj(mountains, mountain_img, 0, 0.25);
			updateRepeatingObj(foreGrasses1, grass2_img, 0, 2.0);
			updateRepeatingObj(foreGrasses2, grass3_img, 0, 3.0);
			
			if (FlxG.keys.justPressed("X"))
			{
				var imgs:Array = obstacleImages[int(Math.random() * obstacleImages.length)];
				addObstacle(imgs[0], imgs[1], imgs[2], imgs[3]);
			}
		}
		
	}	

}